package com.app.base.service.core.organization.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.app.base.config.exception.SaaSException;
import com.app.base.model.dto.EmpListDto;
import com.app.base.model.vo.UsCoVo;
import com.app.base.model.vo.employees.EmployeesListQueryVo;
import com.app.base.service.auth.service.SysUserService;
import com.app.base.service.core.company.entity.Company;
import com.app.base.service.core.company.service.CompanyService;
import com.app.base.model.vo.OrgVo;
import com.app.base.service.core.employees.entity.EmpDetail;
import com.app.base.service.core.employees.service.EmpDetailService;
import com.app.base.service.core.organization.entity.Organization;
import com.app.base.service.core.organization.mapper.OrganizationMapper;
import com.app.base.service.core.organization.service.OrganizationService;
import com.app.base.utlis.result.Result;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 *  服务实现类
 * @author yuhag
 * @since 2022-05-08
 */
@Service
@Slf4j
public class OrganizationServiceImpl extends ServiceImpl<OrganizationMapper, Organization> implements OrganizationService {


    @Resource
    private CompanyService companyService;

    @Resource
    private SysUserService userService;

    @Resource
    private EmpDetailService empDetailService;

    @Override
    public Result saveOrg(HttpServletRequest request, Organization organization) {
        try{
            if (Objects.isNull(organization)){
                throw new SaaSException("组织架构未填写数据,请勿提交空表单!");
            }

            String orgName = organization.getOrganization();
            Integer count = baseMapper.selectCount(new LambdaQueryWrapper<Organization>().eq(Organization::getOrganization, orgName));
            if (count != 0) {
                throw new SaaSException("组织名称重复！");
            }
            UsCoVo info = userService.getUserCompanyInfo(request);
            organization.setModifyBy(info.getUserId());
            organization.setCreatedBy(info.getUserId());
            organization.setCompanyId(info.getCompanyId());

            baseMapper.insert(organization);

            return Result.ok().message("添加成功");
        }catch (Exception e) {
            log.error(e.getMessage());
            return Result.error(e.getMessage());
        }
    }

    @Override
    public Result organizationChart(String userId) {
       try{
           String companyId = userService.getById(userId).getCompanyId();
           List<Organization> organizations = baseMapper.selectList(
                   new LambdaQueryWrapper<Organization>()
                           .eq(Organization::getCompanyId, companyId)
                           .eq(Organization::getGrade,0)
                           .isNull(Organization::getDid));

           Company company = companyService.getById(companyId);

           OrgVo treeOne = new OrgVo(company.getCompanyName(),companyId);
           List<OrgVo> orgList = new ArrayList<>();

           organizations.forEach(org->{
               OrgVo treeTwo = new OrgVo();
               treeTwo.setName(org.getOrganization());
               treeTwo.setLabel(org.getOrganization());
               treeTwo.setValue(org.getId());

               List<Organization> childrenList = baseMapper.selectList(
                       new LambdaQueryWrapper<Organization>()
                               .eq(Organization::getGrade, 1)
                               .eq(Organization::getDid, org.getId()));

               List<OrgVo> orgListTwo = new ArrayList<>();
               childrenList.forEach(children->{
                   OrgVo threeTwo = new OrgVo();
                   threeTwo.setName(children.getOrganization());
                   threeTwo.setLabel(children.getOrganization());
                   threeTwo.setValue(children.getId());
                   orgListTwo.add(threeTwo);
               });

               treeTwo.setChildren(orgListTwo);
               orgList.add(treeTwo);
           });

            treeOne.setChildren(orgList);

            return Result.ok().data("org",treeOne);
       }catch (Exception e) {
           log.error(e.getMessage());
           return Result.error(e.getMessage());
       }
    }

    @Override
    public Result structure(HttpServletRequest request) {
        try{
            UsCoVo info = userService.getUserCompanyInfo(request);
            List<Organization> deptList = baseMapper.selectList(new LambdaQueryWrapper<Organization>()
                    .eq(Organization::getCompanyId, info.getCompanyId())
                    .eq(Organization::getGrade, 0));


            deptList.forEach(org->{
                List<Organization> positionList = baseMapper.selectList(new LambdaQueryWrapper<Organization>()
                        .eq(Organization::getDid,org.getId())
                        .eq(Organization::getGrade,1));
                org.setChildren(positionList);
            });

            return Result.ok(deptList);
        }catch (Exception e) {
            log.error(e.getMessage());
            return Result.error(e.getMessage());
        }
    }

    @Override
    public Result editOrganization(JSONObject json, HttpServletRequest request) {
        try{
            String id = json.getString("id");
            String value = json.getString("value");
            String userId = userService.getUserCompanyInfo(request).getUserId();
            Organization organization = new Organization();
            organization.setId(id);
            organization.setOrganization(value);
            organization.setModifyBy(userId);
            baseMapper.updateById(organization);
            return Result.ok().message("组织架构修改成功！");
        }catch (Exception e) {
            log.error(e.getMessage());
            return Result.error(e.getMessage());
        }
    }

    @Override
    public Result deptList(HttpServletRequest request) {
        try{
            String companyId = userService.getUserCompanyInfo(request).getCompanyId();

            List<Organization> deptList = baseMapper.selectList(new LambdaQueryWrapper<Organization>()
                    .eq(Organization::getGrade, "0")
                    .eq(Organization::getCompanyId, companyId));

            return Result.ok(deptList);
        }catch(Exception e){
            log.error(e.getMessage());
            return Result.error(e.getMessage());
        }
    }

    @Override
    public Result deleteOrganization(Integer grade, String id) {
        try{
            int count = 0;
            if (grade==0) {
                count = empDetailService.count(new LambdaQueryWrapper<EmpDetail>().eq(EmpDetail::getDeptId,id));
            }else {
                count = empDetailService.count(new LambdaQueryWrapper<EmpDetail>().eq(EmpDetail::getPositionId,id));
            }
            if (count == 0){
                if (grade==0) {
                    List<Organization> deptList = baseMapper.selectList(new LambdaQueryWrapper<Organization>()
                            .eq(Organization::getDid, id));
                    deptList.forEach(obj->{
                        baseMapper.deleteById(obj.getId());
                    });
                }else {
                    baseMapper.deleteById(id);
                }
            }else {
                throw new SaaSException("该组织结构下有其员工!");
            }
            return Result.ok().message("删除成功！");
        }catch(Exception e){
            log.error(e.getMessage());
            return Result.error(e.getMessage());
        }
    }

    @Override
    public Result selEmp(Integer grade, String id) {
        try{
            EmployeesListQueryVo employeesListQueryVo = new EmployeesListQueryVo();
            int count = 0;
            if (grade == 0) {
                count = empDetailService.count(new LambdaQueryWrapper<EmpDetail>().eq(EmpDetail::getDeptId, id));
                employeesListQueryVo.setDeptId(id);
            }else {
                count = empDetailService.count(new LambdaQueryWrapper<EmpDetail>().eq(EmpDetail::getPositionId, id));
                employeesListQueryVo.setPositionId(id);
            }
            return empDetailService.empSearchList(1L, (long) count, employeesListQueryVo);
        }catch(Exception e){
            log.error(e.getMessage());
            return Result.error(e.getMessage());
        }
    }
}
